package com.kayak.kboot.dao;

import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.kayak.exception.ErrorException;

/**
 * 1.使用spring的事务管理器机制
 * 2.使用transactionTemplate执行事务
 * 3.暴露出构造方法和inTransaction方法供action中调用
 * 示例如下：
 * 
======================================================================================================================================
    new KTransaction(secondDao,map) {
		@Override
		protected void inTransaction(TransactionStatus status) throws Exception{
				SqlStatement stm =this.getDao().newSqlStatement(SqlManager.getSqlid("batch1").getSql());
				stm.batchUpdateInITransaction((List<Map<String, Object>>) this.getParams().get("list"),false);
		}
	}.execute();
======================================================================================================================================

======================================================================================================================================
	new KTransaction(secondDao,dbMap) {
		@Override
		protected void inTransaction(TransactionStatus status) throws Exception{
			SqlStatement stm1 =this.getDao().newSqlStatement(SqlManager.getSqlid("test1").getSql());
			stm1.autoSetParams(this.getParams());
			stm1.executeUpdate();
			
			SqlStatement stm2 =this.getDao().newSqlStatement(SqlManager.getSqlid("test2").getSql());
			stm2.autoSetParams(this.getParams());
			int i=stm2.executeUpdate();
			if(i>0){
				throw new ErrorException("人为退出测试");
			}
			SqlStatement stm3 =this.getDao().newSqlStatement(SqlManager.getSqlid("test3").getSql());
			stm3.autoSetParams(this.getParams());
			stm3.executeUpdate();
		}
	}.execute();
======================================================================================================================================
 * 
 * @author caix
 *
 */
public abstract class KTransaction extends TransactionCallbackWithoutResult{
	private static Logger log = LoggerFactory.getLogger(KTransaction.class);
	
	private BaseDao dao;
	private Map<String, Object> params;
	
	public KTransaction(BaseDao dao, Map<String, Object> params) {
		super();
		this.dao = dao;
		this.params = params;
	}

	public BaseDao getDao() {
		return dao;
	}

	public void setDao(BaseDao dao) {
		this.dao = dao;
	}

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
	
	protected void doInTransactionWithoutResult(TransactionStatus status) {
		try {
			log.info("================transaction started==============");
			this.getParams().put("transaction_code", "9999");
			inTransaction(status);
			this.getParams().put("transaction_code", "0000");
			log.info("================transaction commited==============");
		} catch (Exception e) {
			
			status.setRollbackOnly();
			e.printStackTrace();
			log.info("================transaction roll back==============");
		}
		
	}
	
	protected abstract void inTransaction(TransactionStatus status)  throws Exception ;
	
	public void execute() throws ErrorException{
		TransactionTemplate transactionTemplate = new TransactionTemplate(this.getDao().transactionManager);  
		transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); 
		transactionTemplate.execute(this);
		if(!this.getParams().get("transaction_code").equals("0000")){
			throw new ErrorException("do transaction err,transaction will not commit.");
		}
		
	}
	
	
	
	
	

}
